/*
 * @Description  : 实用对象方法
 * @Autor        : 杜康
 * @Date         : 2021-08-14 06:28:13 +0800
 * @LastEditors  : 杜康
 * @LastEditTime : 2021-08-14 08:33:17 +0800
 */

/**
 * @description: 检测是不是原始数据类型  JS原始数据类型：Number、String、Boolean、Null、Undefined
 * @param {*} value
 * @return {*}
 * @author: 杜康
 * @Date: 2021-08-14 06:23:46 +0800
 */
const isPrimitive = (value) => {
    return (
        typeof value === "string" ||
        typeof value === "number" ||
        typeof value === "boolean" ||
        typeof value === "undefined" ||
        value === null
    );
};

/**
 * @description: 判断数据是不是引用类型 常见的引用类型：Object、Array、Function
 * 【注】基本类型和引用类型的区别：基本类型的变量存在栈内，
 *  引用类型的值同事保存在栈内存和堆内存的对象；
 *  基本类型的比较是值的比较，引用类型的比较是引用的比较
 * @param {*} obj
 * @return {*}
 * @author: 杜康
 * @Date: 2021-08-14 06:06:29 +0800
 */
const isObject = (obj) => {
    return obj != null && (typeof obj == "object" || typeof obj == "function");
};

/**
 * @description: 获取数据类型
 * @param {*} value
 * @return {*}
 * @author: 杜康
 * @Date: 2021-08-14 06:22:01 +0800
 */
const getType = (value) => {
    return Object.prototype.toString.call(value).slice(8, -1);
};

/**
 * @description: 字符串首位大写
 * @param { String } str
 * @return { String }
 * @author: 杜康
 * @Date: 2021-08-14 06:30:39 +0800
 */
const capitalize = (str) => {
    return str.charAt(0).toUpperCase() + str.slice(1);
};

/**
 * @description: 克隆对象数据，可深度克隆
 * @param {*} value
 * @param {*} deep
 * @return {*}
 * @author: 杜康
 * @Date: 2021-08-14 06:31:54 +0800
 */
const cloneObj = (value, deep) => {
    if (deep) {
        return JSON.parse(JSON.stringify(value));
    } else {
        return Object.assign({}, value);
    }
};

/**
 * @description: 深拷贝，支持常见类型
 * @param { Any } values
 * @return { Any }
 * @author: 杜康
 * @Date: 2021-08-14 08:31:22 +0800
 */
const deepClone = (values) => {
    let copy;
    // Handle the 3 simple types, and null or undefined
    if (null == values || "object" != typeof values) return values;
    // Handle Date
    if (values instanceof Date) {
        copy = new Date();
        copy.setTime(values.getTime());
        return copy;
    }
    // Handle Array
    if (values instanceof Array) {
        copy = [];
        for (let i = 0, len = values.length; i < len; i++) {
            copy[i] = deepClone(values[i]);
        }
        return copy;
    }
    // Handle Object
    if (values instanceof Object) {
        copy = {};
        for (let attr in values) {
            if (values.hasOwnProperty(attr))
                copy[attr] = deepClone(values[attr]);
        }
        return copy;
    }
    throw new Error("Unable to copy values! Its type isn't supported.");
};

/**
 * @description: 判断`obj`是否为空
 * @param { Object } obj
 * @return { Boolean }
 * @author: 杜康
 * @Date: 2021-08-14 08:33:01 +0800
 */
const isEmpty = (obj) => {
    if (!obj || typeof obj !== "object" || Array.isArray(obj)) return false;
    return !Object.keys(obj).length;
}

export default {
    isPrimitive,
    isObject,
    getType,
    capitalize,
    cloneObj,
    deepClone,
    isEmpty,
};
